package Logic

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"golang.org/x/exp/rand"
	"math"
	"server/model"
	"server/response"
	"server/servers"
	"time"
)

// InitUserDiamondLogic 创建角色时初始化角色方块
func InitUserDiamondLogic(ctx *gin.Context, userid int) (err error) {
	var diamonds [5][5]model.DiamondP
	for i := 0; i < 5; i++ {
		for j := 0; j < 5; j++ {
			diamonds[i][j].UserId = userid
			diamonds[i][j].DiamondState = 0
			diamonds[i][j].Number = 0
			diamonds[i][j].Depth = i
			diamonds[i][j].Position = j
			diamonds[i][j].Durability = 0
			err = servers.Svc.DiamondModel.Insert(diamonds[i][j])

		}
	}
	if err != nil {
		response.Fail(ctx, nil, "方块创建出现问题")
		return err
	}
	return err
}

// AdjustProbability 根据depth调整概率分布
func AdjustProbability(depth int) []float64 {
	// 原始权值和概率
	//weights := []int{0, 1, 2, 3, 4}
	baseProbabilities := []float64{0.6, 0.2, 0.15, 0.04, 0.01}

	// 初始化调整后的概率列表
	var adjustedProbabilities []float64

	// 计算调整因子
	adjustmentFactor := math.Sqrt(float64(depth))

	// 计算调整后的概率
	for _, baseProbability := range baseProbabilities {
		// 调整概率
		adjustedProbability := math.Pow(baseProbability, 1/adjustmentFactor)

		// 添加到调整后的概率列表
		adjustedProbabilities = append(adjustedProbabilities, adjustedProbability)
	}

	// 归一化概率
	total := 0.0
	for _, p := range adjustedProbabilities {
		total += p
	}
	normalizedProbabilities := make([]float64, len(adjustedProbabilities))
	for i, p := range adjustedProbabilities {
		normalizedProbabilities[i] = p / total
	}

	return normalizedProbabilities
}

// GetRandomDiamond 根据概率分布生成一个随机权值
func GetRandomDiamond(depth int) int {
	probabilities := AdjustProbability(depth)
	rand.Seed(uint64(time.Now().UnixNano())) // 初始化随机数生成器

	// 生成一个0到1之间的随机数
	r := rand.Float64()

	// 根据概率分布选择权值
	cumulative := 0.0
	for i, p := range probabilities {
		cumulative += p
		if r < cumulative {
			return i // 返回对应的权值
		}
	}

	// 在极端情况下，如果由于浮点数精度问题没有返回值，则返回最后一个权值
	return len(probabilities) - 1
}

// GetRandomNumber 根据方块的种类，生成该方块的资源数量
func GetRandomNumber(depth int, state int) int {
	rand.Seed(uint64(time.Now().UnixNano()))
	//倍率在深度的5-10倍之间
	r := rand.Intn(5) + 5
	var number int
	if state != 0 {
		number = depth * r / state
	} else {
		return 0
	}
	return number

}

// CreateAPageOfGrand 根据深度，创建一整个页面的所有方块信息
func CreateAPageOfGrand(depth int, userid int, ctx *gin.Context) error {
	var diamonds [7][5]model.DiamondP
	for i := 0; i < 7; i++ {

		for j := 0; j < 5; j++ {
			state := GetRandomDiamond(depth)
			number := GetRandomNumber(depth, state)

			diamonds[i][j].UserId = userid
			diamonds[i][j].DiamondState = state
			diamonds[i][j].Number = number
			diamonds[i][j].Depth = depth
			diamonds[i][j].Position = j
			diamonds[i][j].Durability = number*state + 10
			err := servers.Svc.DiamondModel.Insert(diamonds[i][j])
			if err != nil {
				response.Fail(ctx, nil, "方块创建出现问题")
				return err

			}
		}
		depth++
	}
	return nil
}

// GetAPageOfGrand 根据深度得到当前页面的信息
func GetAPageOfGrand(depth int, userid int, ctx *gin.Context) (diamonds [7][5]model.DiamondP, err error) {
	for i := 0; i < 7; i++ {
		diamonds[i], err = servers.Svc.DiamondModel.Select(depth, userid)
		if err != nil {
			response.Fail(ctx, nil, "获取方块信息时出现问题")
			fmt.Println(err)
		}
		depth++
	}
	return diamonds, nil
}

func AddDepth(depth int, userid int) (int, error) {
	if depth == 0 {
		depth += 5
	} else {
		depth += 7
	}
	err := servers.Svc.UserModel.UpdateDepth(userid, depth)
	return depth, err
}

func DecreaseDepth(depth int, userid int) (int, error) {
	if depth == 5 || depth == 0 {
		depth = 0

	} else {
		depth -= 7
	}
	err := servers.Svc.UserModel.UpdateDepth(userid, depth)
	return depth, err
}
